using ERPBackend.Data;
using ERPBackend.Models;
using ERPBackend.Services.Interfaces;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System;

namespace ERPBackend.Services
{
    public class ProductionStockInService : IProductionStockInService
    {
        private readonly ApplicationDbContext _context;
        private readonly IInventoryService _inventoryService;

        public ProductionStockInService(ApplicationDbContext context, IInventoryService inventoryService)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _inventoryService = inventoryService ?? throw new ArgumentNullException(nameof(inventoryService));
        }

        public async Task<IEnumerable<ProductionStockIn>> GetAllProductionStockInsAsync()
        {
            return await _context.ProductionStockIns
                .Include(psi => psi.Workshop)
                .Include(psi => psi.Warehouse)
                .Include(psi => psi.ProductionStockInItems)
                    .ThenInclude(psii => psii.Material)
                .ToListAsync() ?? Enumerable.Empty<ProductionStockIn>();
        }

        public async Task<int> GetTotalProductionStockInsAsync()
        {
            return await _context.ProductionStockIns.CountAsync();
        }

        public async Task<IEnumerable<ProductionStockIn>> GetProductionStockInsPagedAsync(int page, int pageSize)
        {
            int skip = (page - 1) * pageSize;
            return await _context.ProductionStockIns
                .Include(psi => psi.Workshop)
                .Include(psi => psi.Warehouse)
                .OrderByDescending(psi => psi.CreatedTime)
                .Skip(skip)
                .Take(pageSize)
                .ToListAsync() ?? Enumerable.Empty<ProductionStockIn>();
        }

        public async Task<ProductionStockIn?> GetProductionStockInByIdAsync(int id)
        {
            return await _context.ProductionStockIns
                .Include(psi => psi.Workshop)
                .Include(psi => psi.Warehouse)
                .Include(psi => psi.ProductionStockInItems)
                    .ThenInclude(psii => psii.Material)
                .FirstOrDefaultAsync(psi => psi.Id == id);
        }

        public async Task<ProductionStockIn?> GetProductionStockInByCodeAsync(string stockInCode)
        {
            return await _context.ProductionStockIns
                .Include(psi => psi.Workshop)
                .Include(psi => psi.Warehouse)
                .Include(psi => psi.ProductionStockInItems)
                    .ThenInclude(psii => psii.Material)
                .FirstOrDefaultAsync(psi => psi.StockInCode == stockInCode);
        }

        public async Task<ProductionStockIn> CreateProductionStockInAsync(ProductionStockIn productionStockIn)
        {
            // 检查入库单编码是否已存在
            var existingStockIn = await _context.ProductionStockIns
                .FirstOrDefaultAsync(psi => psi.StockInCode == productionStockIn.StockInCode);
            if (existingStockIn != null)
            {
                throw new ArgumentException("入库单编码已存在");
            }

            // 由于系统中没有ProductionOrder表，暂时注释此检查
            // 实际应用中应根据业务需求确认是否需要此检查及如何实现
            // var productionOrder = await _context.ProductionOrders.FindAsync(productionStockIn.ProductionOrderId);
            // if (productionOrder == null)
            // {
            //     throw new ArgumentException("关联的生产订单不存在");
            // }

            // 检查车间是否存在
            var workshop = await _context.Workshops.FindAsync(productionStockIn.WorkshopId);
            if (workshop == null)
            {
                throw new ArgumentException("车间不存在");
            }

            // 检查仓库是否存在
            var warehouse = await _context.Warehouses.FindAsync(productionStockIn.WarehouseId);
            if (warehouse == null)
            {
                throw new ArgumentException("仓库不存在");
            }

            // 设置默认状态为待审核
            productionStockIn.Status = "待审核";
            productionStockIn.CreatedTime = DateTime.Now;
            productionStockIn.UpdatedTime = DateTime.Now;

            // 计算总数量
            if (productionStockIn.ProductionStockInItems != null && productionStockIn.ProductionStockInItems.Any())
            {
                productionStockIn.TotalQuantity = productionStockIn.ProductionStockInItems.Sum(psii => psii.StockInQuantity);
            }
            else
            {
                productionStockIn.TotalQuantity = 0;
            }

            _context.ProductionStockIns.Add(productionStockIn);
            await _context.SaveChangesAsync();
            return productionStockIn;
        }

        public async Task<bool> UpdateProductionStockInAsync(ProductionStockIn productionStockIn)
        {
            // 检查入库单是否存在
            var existingStockIn = await _context.ProductionStockIns.FindAsync(productionStockIn.Id);
            if (existingStockIn == null)
            {
                return false;
            }

            // 检查入库单编码是否已被其他入库单使用
            if (existingStockIn.StockInCode != productionStockIn.StockInCode &&
                await _context.ProductionStockIns.AnyAsync(psi => psi.StockInCode == productionStockIn.StockInCode))
            {
                throw new ArgumentException("入库单编码已被使用");
            }

            // 由于系统中没有ProductionOrder表，暂时注释此检查
            // 实际应用中应根据业务需求确认是否需要此检查及如何实现
            // if (productionStockIn.ProductionOrderId != existingStockIn.ProductionOrderId)
            // {
            //     var productionOrder = await _context.ProductionOrders.FindAsync(productionStockIn.ProductionOrderId);
            //     if (productionOrder == null)
            //     {
            //         throw new ArgumentException("关联的生产订单不存在");
            //     }
            // }

            // 检查车间是否存在
            if (productionStockIn.WorkshopId != existingStockIn.WorkshopId)
            {
                var workshop = await _context.Workshops.FindAsync(productionStockIn.WorkshopId);
                if (workshop == null)
                {
                    throw new ArgumentException("车间不存在");
                }
            }

            // 检查仓库是否存在
            if (productionStockIn.WarehouseId != existingStockIn.WarehouseId)
            {
                var warehouse = await _context.Warehouses.FindAsync(productionStockIn.WarehouseId);
                if (warehouse == null)
                {
                    throw new ArgumentException("仓库不存在");
                }
            }

            // 更新属性
            existingStockIn.StockInCode = productionStockIn.StockInCode;
            existingStockIn.ProductionOrderId = productionStockIn.ProductionOrderId;
            existingStockIn.WorkshopId = productionStockIn.WorkshopId;
            existingStockIn.StockInDate = productionStockIn.StockInDate;
            existingStockIn.WarehouseId = productionStockIn.WarehouseId;
            existingStockIn.Status = productionStockIn.Status;
            existingStockIn.TotalQuantity = productionStockIn.TotalQuantity;
            existingStockIn.Remark = productionStockIn.Remark;
            existingStockIn.UpdatedBy = productionStockIn.UpdatedBy;
            existingStockIn.UpdatedTime = DateTime.Now;

            _context.Entry(existingStockIn).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> DeleteProductionStockInAsync(int id)
        {
            var productionStockIn = await _context.ProductionStockIns.FindAsync(id);
            if (productionStockIn == null)
            {
                return false;
            }

            // 检查是否有相关的明细
            var hasItems = await _context.ProductionStockInItems
                .AnyAsync(psii => psii.ProductionStockInId == id);
            if (hasItems)
            {
                // 先删除明细
                var items = await _context.ProductionStockInItems
                    .Where(psii => psii.ProductionStockInId == id)
                    .ToListAsync();
                _context.ProductionStockInItems.RemoveRange(items);
            }

            _context.ProductionStockIns.Remove(productionStockIn);
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> ChangeProductionStockInStatusAsync(int id, string status, int? updatedBy)
        {
            var productionStockIn = await _context.ProductionStockIns.FindAsync(id);
            if (productionStockIn == null)
            {
                return false;
            }

            if (updatedBy == null)
            {
                throw new ArgumentNullException(nameof(updatedBy), "更新人不能为空");
            }

            productionStockIn.Status = status;
            productionStockIn.UpdatedBy = updatedBy.Value;
            productionStockIn.UpdatedTime = DateTime.Now;

            _context.Entry(productionStockIn).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> ApproveProductionStockInAsync(int id, int approvedBy, string? approvalRemark = null)
        {
            var productionStockIn = await _context.ProductionStockIns.FindAsync(id);
            if (productionStockIn == null)
            {
                return false;
            }

            // 检查是否为待审核状态
            if (productionStockIn.Status != "待审核")
            {
                throw new ArgumentException("只有待审核状态的入库单才能进行审批");
            }

            // 更新状态和审核信息
            productionStockIn.Status = "已审核";
            productionStockIn.ApprovedBy = approvedBy;
            productionStockIn.ApprovedTime = DateTime.Now;
            productionStockIn.UpdatedBy = approvedBy; // 假设approvedBy不为null，实际应用中应添加null检查
            productionStockIn.UpdatedTime = DateTime.Now;
            if (!string.IsNullOrEmpty(approvalRemark))
            {
                productionStockIn.Remark = approvalRemark;
            }

            // 获取明细
            var items = await _context.ProductionStockInItems
                .Include(psii => psii.Material)
                .Where(psii => psii.ProductionStockInId == id)
                .ToListAsync();

            // 更新库存
            foreach (var item in items)
            {
                // 假设操作人为当前审核人，实际应用中应根据业务需求确定操作人
                await _inventoryService.UpdateInventoryQuantityAsync(
                    item.MaterialId,
                    productionStockIn.WarehouseId,
                    item.StockInQuantity,
                    (byte)0, // 操作类型，假设0表示入库
                    "生产入库",
                    approvedBy
                );
            }

            _context.Entry(productionStockIn).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }
    }
}